package com.neusoft.hifly.lock.annotation;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.neusoft.hifly.lock.RedissonLock;
import com.neusoft.hifly.lock.utils.Log;

/**
 * Redisson分布式锁注解解析器
 */
@Aspect
@Component
public class DistributedLockHandler {

	@Autowired(required = false)
	private RedissonLock redissonLock;

	@Around("@annotation(distributedLock)")
	public void around(final ProceedingJoinPoint joinPoint, final DistributedLock distributedLock) {
		Log.info("[开始]执行RedisLock环绕通知,获取Redis分布式锁开始");
		//获取锁名称
		final String lockName = distributedLock.value();
		//获取超时时间，默认10秒
		final int leaseTime = distributedLock.leaseTime();
		redissonLock.lock(lockName, leaseTime);
		try {
			Log.info("获取Redis分布式锁[成功]，加锁完成，开始执行业务逻辑...");
			joinPoint.proceed();
		} catch (final Throwable throwable) {
			Log.info("获取Redis分布式锁[异常]，加锁失败", throwable);
			throwable.printStackTrace();
		} finally {
			//如果该线程还持有该锁，那么释放该锁。如果该线程不持有该锁，说明该线程的锁已到过期时间，自动释放锁
			if (redissonLock.isHeldByCurrentThread(lockName)) {
				redissonLock.unlock(lockName);
			}
		}
		Log.info("释放Redis分布式锁[成功]，解锁完成，结束业务逻辑...");
	}
}
